import React, { useContext } from 'react'
const EMPTY: unique symbol = Symbol('空的上下文');

export interface ContainerProviderProps<State = void> {
    initialState?: State;
    children: React.ReactNode
}

export interface Container<Value, State = void> {
    Provider: React.ComponentType<ContainerProviderProps<State>>
    useContainer: () => Value;
}

export function createContainer<Value, State = void>(
    useHook: (initialState?: State) => Value,
): Container<Value, State> {
    const Context = React.createContext<Value | typeof EMPTY>(EMPTY)
    return {
        Provider(props: ContainerProviderProps<State>) {
            const value = useHook(props.initialState);
            return (
                <Context.Provider value={value}>{props.children}</Context.Provider>
            )
        },
        useContainer() {
            const value = useContext(Context);
            if (value === EMPTY) {
                throw new Error('Component must be wrapped with <Container.Provider>');
            }
            return value
        },
    };
}

export function useContainer<Value, State = void>(
    container: Container<Value, State>,
): Value {
    return container.useContainer()
}